/*
 * @Author: wangze@linkstec.com
 * @Date: 2022-01-18 09:37:08
 * @Function: Please Input Function
 */
// import axios from 'axios'
import store from '../store';
import { loading, notify } from '.';
import DevMock from '@/config/devMock';

import { VINTEXFUND_USER_TOKEN } from '@/utils/constant';
import { requestQueue } from './requestQueue';

const SUCCESS_CODE = '0';
const REDIRECT_CODE = '401';
const WARNING_CODE = '600';
// const ERROR_101 = '101';
const REDIRECT_URL = process.env.VUE_APP_COSWEBURL;

// 创建axios实例
const service = axios.create({
  baseURL: process.env.VUE_APP_APIURL,
  timeout: 30000, // 请求超时时间
  withCredentials: true
});

service.interceptors.request.use(function (config) {
  const { headers = {} } = config;
  const { allowMulti } = headers;
  if (!allowMulti) {
    // 将请求加入队列，并取消上次相同url的请求
    requestQueue.add(config, axios.CancelToken.source());
  }

  const vintexfundToken = store.state.vintexfundToken;
  // header添加token
  if (vintexfundToken) {
    // const headers = config.headers || {};
    if (config.url.indexOf('/sys/login') === -1 && config.url.indexOf('/sys/init') === -1) {
      headers['AUTHORIZATION'] = vintexfundToken;
    }
    config.headers = headers;
  }

  return config;
}, function (error) {
  return Promise.reject(error);
});

service.interceptors.response.use(function (response) {
  const { headers = {} } = response.config;
  const { allowMulti } = headers;
  if (!allowMulti) {
    // 从请求队列中移除
    requestQueue.remove(response.config);
  }
  if (response.status === 200) {
    return response.data;
  }
  return Promise.reject(response);
}, function (error) {
  const { headers = {} } = error.config || {};
  const { allowMulti } = headers;
  if (!allowMulti) {
    // 从请求队列中移除
    requestQueue.remove(error.config);
  }
  return Promise.reject(error);
});

/**
 * Axios 封装
 * @param {String} url - 接口地址
 * @param {Object} settings - 特别设置
 * @param {Object} config - axios 配置
 * @returns Promise
 */
function invoke (url, settings, config) {
  const defaultSettings = {
    showLoading: 1, // 显示全局loading
    showErrorNotify: 1, // 显示错误信息
    allowMulti: 0 // 允许同时请求多次相同接口, 而不取消上一次
  };
  const { showLoading, showErrorNotify, allowMulti } = { ...defaultSettings, ...settings };

  if (!config) {
    config = {};
  }
  config.url = url.includes('http') ? url : process.env.VUE_APP_VINTEXFUND_APIURL + url;
  config.headers = { ...config.headers, ...{ allowMulti } };

  if (showLoading) {
    loading(true);
  }
  return service.request(config).catch(err => {
    const isCancel = err.__CANCEL__;
    if (showErrorNotify && !isCancel) {
      notify('系统忙，请稍后再试');
    }
    return Promise.reject(err);
  }).then(async res => {
    const isBlob = res instanceof Blob;
    if (isBlob) {
      const blobObj = await BlobToObject(res);
      if (blobObj?.retCode) {
        res = blobObj;
      }
    }
    const { retCode: code, retCodeMsg: msg } = res;

    // 成功
    if (code === SUCCESS_CODE) {
      return res;
    }

    // 重定向
    if (code === REDIRECT_CODE) {
      // 开发环境跳过登录，返回重定向码不再跳转
      if (process.env.NODE_ENV === 'development' && DevMock.SKIP_LOGIN) {
        return res;
      }
      // 清空缓存；
      localStorage.removeItem(VINTEXFUND_USER_TOKEN);
      store.commit('updateVintexfundToken', {
        vintexfundToken: null
      });
      store.commit('updateUserInfo', {});
      window.location.href = REDIRECT_URL;
      return;
    }

    // 警告提示
    if (code === WARNING_CODE) {
      if (showErrorNotify) notify(removeFirstColonFront(msg), 'warning');
      return Promise.reject(res);
    }

    // 错误提示
    if (code) {
      if (showErrorNotify) notify(msg);
      return Promise.reject(res);
    } else {
      // 返回值为文件流
      return res;
    }
  }).finally(() => {
    if (showLoading) {
      loading(false);
    }
  });
}

function BlobToObject (blob) {
  return new Promise((resolve, reject) => {
    try {
      const { type } = blob;
      if (type === 'application/json') {
        const file = new FileReader();
        let json = {};
        file.readAsText(blob, 'utf-8');
        file.onload = function () {
          json = JSON.parse(file.result);
          resolve(json);
        };
      } else {
        resolve({});
      }
    } catch (err) {
      resolve({ err });
    }
  });
}

/**
 * 删除字符串第一个冒号之前的字符
 * '[w790010]:xxx' -> 'xxx'
 * @param {string} msg 处理的字符出
 * @returns
 */
function removeFirstColonFront (msg) {
  const arr = String(msg).split(':');
  arr.shift();
  return arr.join(':');
}

service.invoke = invoke;

export default service;
